package com.aco.party.web.controller.client;

import com.aco.party.model.po.User;
import com.aco.party.model.vo.AccessTokenVo;
import com.aco.party.model.vo.WeixinUserInfo;
import com.aco.party.security.token.OpenIdAuthenticationToken;
import com.aco.party.service.system.UserService;
import com.aco.party.util.ConfigResource;
import com.aco.party.util.WebModelUtil;
import com.aco.party.web.controller.system.BaseController;
import com.qq.connect.QQConnectException;
import com.qq.connect.api.OpenID;
import com.qq.connect.javabeans.AccessToken;
import com.qq.connect.javabeans.qzone.UserInfoBean;
import com.qq.connect.oauth.Oauth;
import com.qq.connect.api.qzone.UserInfo;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import weibo4j.Account;
import weibo4j.Users;
import weibo4j.model.WeiboException;
import weibo4j.org.json.JSONObject;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;

/**
 * Created by flying on 5/4/2016 0004.
 */
@Controller
public class ThirdLoginController extends BaseController {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Resource
    private UserService userService;

    private final String WEIBOPREFIX = "wb_";
    private final String WEIXINPREFIX = "wx__";
    private final String QQPREFIX = "qq___";

    private class LoginUser{
        String openId;  //带前缀的openId

        String nickName;

        public LoginUser(String openId, String nickName) {
            this.openId = openId;
            this.nickName = nickName;
        }

        public String getOpenId() {
            return openId;
        }

        public void setOpenId(String openId) {
            this.openId = openId;
        }

        public String getNickName() {
            return nickName;
        }

        public void setNickName(String nickName) {
            this.nickName = nickName;
        }
    }

    private String commonLogin(LoginUser loginUser,RedirectAttributes attributes){
        User user = userService.findUserByOpenId(loginUser.getOpenId());
        if(user == null){
            //如果不存在则跳转到填写基础信息页面
            attributes.addAttribute("openId",loginUser.getOpenId());
            attributes.addAttribute("nickName",loginUser.getNickName());
            return "redirect:addProfile";
        }else{
            //存在登录信息，进行登录处理，并跳转到首页
            OpenIdAuthenticationToken token = new OpenIdAuthenticationToken(user.getUsername(), user.getUsername(),user.getPassword());
            SecurityUtils.getSubject().login(token);
            return "redirect:/home";
        }
    }

    @RequestMapping("/weiboLogin")
    public void weiboLogin(HttpServletResponse response){
        weibo4j.Oauth oauth = new weibo4j.Oauth();
        try {
            response.sendRedirect(oauth.authorize("code"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @RequestMapping("/weiboLoginCallback")
    public String weiboLoginCallback(String code, RedirectAttributes attributes) {
        weibo4j.Oauth oauth = new weibo4j.Oauth();
        weibo4j.http.AccessToken accessTokenObj = null;
        try {
            accessTokenObj = oauth.getAccessTokenByCode(code);
        } catch (WeiboException e) {
            e.printStackTrace();
        }
        if (accessTokenObj != null) {
            String accString = accessTokenObj.getAccessToken();

            Account am = new Account(accString);
            JSONObject uid = null;
            try {
                uid = am.getUid();
                Users um = new Users(accString);

                weibo4j.model.User webuser = um.showUserById(uid.getString("uid"));
                logger.info("获取到的微博信息为：" + webuser);
                LoginUser loginUser = new LoginUser(WEIBOPREFIX + webuser.getId(),webuser.getScreenName());
                return commonLogin(loginUser,attributes);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        logger.warn("微博登录授权失败！");
        return "";
    }

    @RequestMapping("/invalidWeiboLoginCallback")
    public String invalidWeiboLogin(String code) {
        logger.info(code);
        return "";
    }

    @RequestMapping("/qqLogin")
    public void qqLogin(HttpServletRequest request, HttpServletResponse response) {
        try {
            response.sendRedirect(new Oauth().getAuthorizeURL(request));
        } catch (QQConnectException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @RequestMapping("/qqLoginCallback")
    public String qqLoginCallback(HttpServletRequest request, HttpServletResponse response, RedirectAttributes attributes) {


        String accessToken = null,
                openID = null;
        long tokenExpireIn = 0L;
        try {
            AccessToken accessTokenObj = (new Oauth()).getAccessTokenByRequest(request);
            if (accessTokenObj.getAccessToken().equals("")) {
                logger.error("没有获取到响应参数");
            } else {
                accessToken = accessTokenObj.getAccessToken();
                tokenExpireIn = accessTokenObj.getExpireIn();

                request.getSession().setAttribute("access_token", accessToken);
                request.getSession().setAttribute("token_expirein", String.valueOf(tokenExpireIn));

                // 利用获取到的accessToken 去获取当前用的openid -------- start
                OpenID openIDObj = new OpenID(accessToken);
                openID = openIDObj.getUserOpenID();

                logger.info("欢迎你，代号为 " + openID + " 的用户!");
                request.getSession().setAttribute("openid", openID);
                logger.info("<a href=" + "/shuoshuoDemo.html" + " target=\"_blank\">去看看发表说说的demo吧</a>");
                // 利用获取到的accessToken 去获取当前用户的openid --------- end


                logger.info("<p> start -----------------------------------利用获取到的accessToken,openid 去获取用户在Qzone的昵称等信息 ---------------------------- start </p>");
                UserInfo qzoneUserInfo = new UserInfo(accessToken, openID);
                UserInfoBean userInfoBean = qzoneUserInfo.getUserInfo();
                logger.info("<br/>");
                if (userInfoBean.getRet() == 0) {
                    logger.info(userInfoBean.getNickname() + "<br/>");
                    logger.info(userInfoBean.getGender() + "<br/>");
                    logger.info("黄钻等级： " + userInfoBean.getLevel() + "<br/>");
                    logger.info("会员 : " + userInfoBean.isVip() + "<br/>");
                    logger.info("黄钻会员： " + userInfoBean.isYellowYearVip() + "<br/>");
                    logger.info("<image src=" + userInfoBean.getAvatar().getAvatarURL30() + "/><br/>");
                    logger.info("<image src=" + userInfoBean.getAvatar().getAvatarURL50() + "/><br/>");
                    logger.info("<image src=" + userInfoBean.getAvatar().getAvatarURL100() + "/><br/>");


                    LoginUser loginUser = new LoginUser(QQPREFIX + openID,userInfoBean.getNickname());
                    return commonLogin(loginUser,attributes);


                } else {
                    logger.info("很抱歉，我们没能正确获取到您的信息，原因是： " + userInfoBean.getMsg());
                }
                logger.info("<p> end -----------------------------------利用获取到的accessToken,openid 去获取用户在Qzone的昵称等信息 ---------------------------- end </p>");
            }
        } catch (Exception e) {
            logger.error(StringUtils.join(e.getStackTrace()));
        }
        return "";
    }

    @RequestMapping("/weixinLogin")
    public String weixinLogin(HttpServletRequest request){
        String url = String.format("https://open.weixin.qq.com/connect/qrconnect?" +
                "appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_login&state=%s#wechat_redirect",
                ConfigResource.getSystemProperty("weixin_app_id"),
                URLEncoder.encode(ConfigResource.getSystemProperty("weixin_redirect_uri")),
                request.getSession().getId());
        return "redirect:" + url;
    }

    @RequestMapping(value = "/weixinLoginCallback")
    public String weixinLoginCallback(HttpServletRequest request,String code,String state,RedirectAttributes attributes){
        //state
        // 用于保持请求和回调的状态，授权请求后原样带回给第三方。
        // 该参数可用于防止csrf攻击（跨站请求伪造攻击），建议第三方带上该参数，可设置为简单的随机数加session进行校验
        if(!state.equals(request.getSession().getId())){
            logger.warn("防止csrf攻击（跨站请求伪造攻击）成功！");
        }

        AccessTokenVo accessTokenVo = WebModelUtil.getAccessToken(code);

        if(accessTokenVo != null){
            logger.info("获取到的accessTokenVo是：" + accessTokenVo);
            WeixinUserInfo weixinUserInfo = WebModelUtil.getUserInfo(accessTokenVo.getAccess_token(), accessTokenVo.getOpenid());
            if(weixinUserInfo != null){
                LoginUser loginUser = new LoginUser(WEIXINPREFIX + accessTokenVo.getOpenid(),weixinUserInfo.getNickname());
                return commonLogin(loginUser,attributes);
            }
        }
        logger.warn("微信登录失败！");
        return "";
    }


}
